package com.beaven.imserver.net.factory;

import com.beaven.imserver.net.bean.db.Group;
import com.beaven.imserver.net.bean.db.GroupMember;
import com.beaven.imserver.net.bean.db.User;
import com.beaven.imserver.net.utils.HibUtil;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * author: Beaven
 * time: 2017/5/31 18:27
 */
public class GroupFactory {
  public static Group findById(String groupId) {
    return HibUtil.query(session -> (Group) session.createQuery("from Group where id=:groupId")
        .setParameter("groupId", groupId)
        .uniqueResult());
  }

  public static Group findById(User user, String groupId) {
    // 查询一个群, 同时该User必须为群的成员，否则返回null
    GroupMember groupMember = findMember(groupId, user.getId());
    if (groupMember != null) {
      return HibUtil.query(session -> (Group) session.createQuery("from Group where id=:groupId")
          .setParameter("groupId", groupId)
          .uniqueResult());
    } else {
      return null;
    }
  }

  @SuppressWarnings("unchecked")
  public static Set<GroupMember> getMembers(Group group) {
    List<GroupMember> memberList =
        HibUtil.query(
            session -> (List<GroupMember>) session.createQuery("from GroupMember where groupId=:id")
                .setParameter("id", group.getId())
                .list());
    return new HashSet<>(memberList);
  }

  public static Group findByName(String name, User user) {
    return HibUtil.query(session -> {
      session.load(user, user.getId());
      return (Group) session
          .createQuery("from Group where ownerId=:ownerId and name=:name")
          .setParameter("ownerId", user.getId())
          .setParameter("name", name).uniqueResult();
    });
  }

  public static Group createGroup(String groupName, User self) {
    Group group = new Group();
    group.setName(groupName);
    group.setOwner(self);
    group.setOwnerId(self.getId());
    return HibUtil.query(session -> {
      session.save(group);
      return group;
    });
  }

  public static Group updateGroup(Group group) {
    return HibUtil.query(session -> {
      session.saveOrUpdate(group);
      return group;
    });
  }

  @SuppressWarnings("unchecked")
  public static void deleteGroup(Group group) {
    Set<GroupMember> members = getMembers(group);
    for (GroupMember member : members) {
      HibUtil.queryOnly(session -> {
        session.delete(member);
      });
    }
    HibUtil.queryOnly(session -> {
      session.delete(group);
    });
  }

  public static GroupMember findOwnerMember(Group group) {
    return findMember(group.getId(), group.getOwnerId());
  }

  public static GroupMember findMember(String groupId, String userId) {
    return HibUtil.query(session -> (GroupMember) session.createQuery(
        "from GroupMember where userId=:userId and groupId=:groupId")
        .setParameter("userId", userId)
        .setParameter("groupId", groupId)
        .uniqueResult());
  }

  public static GroupMember createGroupMember(Group group, User user, boolean isOwner) {
    GroupMember member = new GroupMember();
    member.setGroup(group);
    member.setGroupId(group.getId());
    member.setUser(user);
    member.setUserId(user.getId());
    member.setPermissionType(
        isOwner ? GroupMember.PERMISSION_TYPE_ADMIN_SU : GroupMember.PERMISSION_TYPE_NONE);
    return HibUtil.query(session -> {
      session.save(member);
      return member;
    });
  }

  public static void deleteGroupMember(Group group, User user) {
    GroupMember groupMember = findMember(group.getId(), user.getId());
    if (groupMember == null) {
      return;
    }
    HibUtil.queryOnly(session -> {
      session.delete(groupMember);
    });
  }

  @SuppressWarnings("unchecked")
  public static List<GroupMember> findGroupMembers(String userId) {
    return HibUtil.query(
        session -> (List<GroupMember>) session.createQuery("from GroupMember where userId=:userId")
            .setParameter("userId", userId)
            .list());
  }
}
